package com.ctshk.rpc.system.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.ctshk.common.enums.SupplierStatus;
import com.ctshk.rpc.system.dto.OrderCollectionSumDTO;
import com.ctshk.rpc.system.req.*;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.constant.CurrencyIdCode;
import com.ctshk.common.constant.CurrencyRateExchangeConstant;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.system.dto.MainDataCurrencyListDTO;
import com.ctshk.rpc.system.dto.MainDataCurrencyQueryDTO;
import com.ctshk.rpc.system.entity.MainDataCurrency;
import com.ctshk.rpc.system.mapper.MainDataCurrencyMapper;
import com.ctshk.rpc.system.service.IMainDataCurrencyService;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-29
 */
@DubboService
public class MainDataCurrencyServiceImpl extends ServiceImpl<MainDataCurrencyMapper, MainDataCurrency> implements IMainDataCurrencyService {

    @Autowired
    private MainDataCurrencyMapper mainDataCurrencyMapper;

    /**
     * 新增币种
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(MainDataCurrencyAddReq req) {
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("currency_code",req.getCurrencyCode())
                .or().eq("currency_name",req.getCurrencyName())
                .or().eq("currency_symbol",req.getCurrencySymbol());
        queryWrapper.eq("is_deleted",IsDeletedCode.NO.getCode());
        MainDataCurrency selectOne = mainDataCurrencyMapper.selectOne(queryWrapper);
        if(null != selectOne){
            return Result.failed(SystemError.SYS_413);
        }
        MainDataCurrency mainDataCurrency = EntityUtil.copy(req, MainDataCurrency.class);
        long id = IdWorker.getId();
        mainDataCurrency.setId(id);
        LocalDateTime now = LocalDateTime.now();
        mainDataCurrency.setGmtCreate(now);
        mainDataCurrency.setGmtModified(now);
        mainDataCurrency.setModifiedId(req.getCreateId());
        mainDataCurrency.setIsDeleted(IsDeletedCode.NO.getCode());
        mainDataCurrencyMapper.insert(mainDataCurrency);
        return Result.success(id);
    }

    /**
     * 编辑币种
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result update(MainDataCurrencyUpdateReq req) {
        MainDataCurrency mainDataCurrency = EntityUtil.copy(req, MainDataCurrency.class);
        LocalDateTime now = LocalDateTime.now();
        mainDataCurrency.setGmtModified(now);
        mainDataCurrencyMapper.updateById(mainDataCurrency);
        return Result.success(req.getId());
    }

    /**
     * 编辑币种状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateStatus(MainDataCurrencyUpdateStatusReq req) {
        MainDataCurrency mainDataCurrency = EntityUtil.copy(req, MainDataCurrency.class);
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",req.getId());
        queryWrapper.eq("is_deleted",IsDeletedCode.NO.getCode());
        MainDataCurrency selectOne = mainDataCurrencyMapper.selectOne(queryWrapper);
        if(selectOne.getStatus() == 0){
            mainDataCurrency.setStatus(1);
        }else {
            mainDataCurrency.setStatus(0);
        }
        mainDataCurrencyMapper.updateById(mainDataCurrency);
        return Result.success(req.getId());
    }
    /**
     *查询币种列表
     */
    @Override
    public PageResponse<MainDataCurrencyListDTO> list(MainDataCurrencyListReq req) {
        Page<MainDataCurrency> page = new Page<>(req.getPageNo(), req.getPageSize());
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MainDataCurrency::getIsDeleted,IsDeletedCode.NO.getCode());
        queryWrapper.lambda().eq(null != req.getStatus(),MainDataCurrency::getStatus,req.getStatus());
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getName()),MainDataCurrency::getCurrencyName,req.getName())
                .or().like(StringUtils.isNotBlank(req.getName()),MainDataCurrency::getCurrencyCode,req.getName())
                .or().like(StringUtils.isNotBlank(req.getName()),MainDataCurrency::getCurrencySymbol,req.getName());
        //需定义排序规则:按修改时间倒序
        queryWrapper.lambda().orderByDesc(MainDataCurrency::getGmtModified);
        Page<MainDataCurrency> iPage = baseMapper.selectPage(page, queryWrapper);
        List<MainDataCurrency> mainDataCurrencyList = iPage.getRecords();
        if (CollectionUtils.isEmpty(mainDataCurrencyList)) {
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        List<MainDataCurrencyListDTO> mainDataCurrencyListDTOS = EntityUtil.copyList(mainDataCurrencyList, MainDataCurrencyListDTO.class);
        return new PageResponse<>(mainDataCurrencyListDTOS, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public MainDataCurrencyListDTO getCurrencyByCode(String code) {
        QueryWrapper<MainDataCurrency> qw = new QueryWrapper<>();
        qw.lambda().eq(MainDataCurrency::getIsDeleted, IsDeletedCode.NO.getCode())
                .eq(MainDataCurrency::getStatus, SupplierStatus.ENABLE.getCode())
                .eq(MainDataCurrency::getCurrencyCode, code);
        MainDataCurrency mdc = baseMapper.selectOne(qw);
        if(mdc != null){
            return EntityUtil.copy(mdc,MainDataCurrencyListDTO.class);
        }
        return null;
    }

    /**
     *查询币种
     */
    @Override
    public Result<MainDataCurrencyQueryDTO> query(MainDataCurrencyUpdateStatusReq req) {
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",req.getId());
        queryWrapper.eq("is_deleted",IsDeletedCode.NO.getCode());
        MainDataCurrency mainDataCurrency = mainDataCurrencyMapper.selectOne(queryWrapper);
        MainDataCurrencyQueryDTO mainDataCurrencyQueryDTO = EntityUtil.copy(mainDataCurrency, MainDataCurrencyQueryDTO.class);
        return Result.success(mainDataCurrencyQueryDTO);
    }

    @Override
    public List<MainDataCurrencyQueryDTO> queryList(List<Long> req) {
        if(CollectionUtils.isEmpty(req)){
            return null;
        }
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(MainDataCurrency::getId,req);
        List<MainDataCurrency> mainDataCurrencies = baseMapper.selectList(queryWrapper);
        List<MainDataCurrencyQueryDTO> mainDataCurrencyQueryDTOS = EntityUtil.copyList(mainDataCurrencies, MainDataCurrencyQueryDTO.class);
        return mainDataCurrencyQueryDTOS;
    }


    /**
     * author gzl-wansi001
     * 获取币种汇率
     * @param currencyCode          币种编码
     * @param rateExchangeType      汇率类型 1. 计划兑换率 2.门市兑换率 3.crm兑换率 4.财务兑换率
     * @return
     */
    @Override
    public BigDecimal getExchangeRate(String currencyCode, String rateExchangeType) {
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isBlank(currencyCode)){
            return BigDecimal.ZERO;
        }
        queryWrapper.lambda().like(MainDataCurrency::getCurrencyCode,currencyCode);
        List<MainDataCurrency> mainDataCurrencies = baseMapper.selectList(queryWrapper);

        if(CollectionUtils.isEmpty(mainDataCurrencies)){
            return BigDecimal.ZERO;
        }

        MainDataCurrency mainDataCurrency = mainDataCurrencies.stream().findFirst().get();
        switch (rateExchangeType){
            //计划兑换率
            case CurrencyRateExchangeConstant.PLANNED_EXCHANGE_RATE_:
                return mainDataCurrency.getPlannedExchangeRate();
            //门市兑换率
            case CurrencyRateExchangeConstant.MARKET_EXCHANGE_RATE_:
                return mainDataCurrency.getMarketExchangeRate();
            //crm兑换率
            case CurrencyRateExchangeConstant.CRM_EXCHANGE_RATE_:
                return mainDataCurrency.getCrmExchangeRate();
            //财务兑换率
            case CurrencyRateExchangeConstant.FINANCIAL_EXCHANGE_RATE_:
                return mainDataCurrency.getFinancialExchangeRate();
            default:
                break;

        }
        return BigDecimal.ZERO;
    }

    /**
     * author gzl-wansi001
     * 获取币种信息
     * @param currencyCode          币种编码
     * @param rateExchangeType      汇率类型 1. 计划兑换率 2.门市兑换率 3.crm兑换率 4.财务兑换率
     * @return
     */
    @Override
    public MainDataCurrencyQueryDTO getExchangeCurrencyEntity(String currencyCode, String rateExchangeType) {
        QueryWrapper<MainDataCurrency> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isBlank(currencyCode)){
            return new MainDataCurrencyQueryDTO();
        }
        queryWrapper.lambda().like(MainDataCurrency::getCurrencyCode,currencyCode);
        List<MainDataCurrency> mainDataCurrencies = baseMapper.selectList(queryWrapper);

        if(CollectionUtils.isEmpty(mainDataCurrencies)){
            return new MainDataCurrencyQueryDTO();
        }

        MainDataCurrency mainDataCurrency = mainDataCurrencies.stream().findFirst().orElse(null);
        if(mainDataCurrency != null){
            return EntityUtil.copy(mainDataCurrency,MainDataCurrencyQueryDTO.class);
        }
        return new MainDataCurrencyQueryDTO();
    }

    /**
     * 根据币种兑换港币金额
     *
     * @param currencyId
     * @param amount
     * @return
     */
    @Override
    public BigDecimal getHkdAmount(Long currencyId, BigDecimal amount) {
        if (currencyId == null || amount == null){
            throw new BusinessException(SystemError.SYS_402);
        }
        if (Objects.equals(CurrencyIdCode.HKD.getCode(),currencyId)){
            return amount;
        }
        MainDataCurrency currency = getById(currencyId);
        if (currency == null || Objects.equals(currency.getIsDeleted(),1)){
            throw new BusinessException(SystemError.SYS_411);
        }
        //门市汇率
        if (currency.getMarketExchangeRate() == null){
            throw new BusinessException(SystemError.SYS_411);
        }
        return currency.getMarketExchangeRate().multiply(amount);
    }

    /**
     * 订单收款本位币金额统计
     *
     * @param list
     * @return
     */
    @Override
    public OrderCollectionSumDTO orderCollectionSum(List<OrderCollectionSumReq> list) {
        OrderCollectionSumDTO dto = null;
        if (CollectionUtils.isNotEmpty(list)){
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (OrderCollectionSumReq item : list) {
                if (item.getCurrencyTypeId() == null || item.getPaidInAmount() == null){
                    continue;
                }
                if (Objects.equals(CurrencyIdCode.HKD.getCode(),item.getCurrencyTypeId())){
                    item.setHkdAmount(item.getPaidInAmount());
                    totalAmount = totalAmount.add(item.getPaidInAmount());
                }
                MainDataCurrency currency = getById(item.getCurrencyTypeId());
                if (currency == null || Objects.equals(currency.getIsDeleted(),1)){
                    throw new BusinessException(SystemError.SYS_411);
                }
                //门市汇率
                if (currency.getMarketExchangeRate() == null){
                    throw new BusinessException(SystemError.SYS_411);
                }
                BigDecimal hkdAmount = currency.getMarketExchangeRate().multiply(item.getPaidInAmount());
                item.setHkdAmount(hkdAmount);
                totalAmount = totalAmount.add(hkdAmount);
            }
            dto = new OrderCollectionSumDTO();
            dto.setTotalAmount(totalAmount);
            dto.setItemList(list);
        }
        return dto;
    }

    @Override
    public BigDecimal getHkdAmountByType(Long currencyId, String rateExchangeType, BigDecimal amount) {
        if (currencyId == null || amount == null){
            throw new BusinessException(SystemError.SYS_402);
        }
        if (Objects.equals(CurrencyIdCode.HKD.getCode(),currencyId)){
            return amount;
        }
        MainDataCurrency currency = getById(currencyId);
        if (currency == null || Objects.equals(currency.getIsDeleted(),1)){
            throw new BusinessException(SystemError.SYS_411);
        }
        //门市汇率
        if (currency.getMarketExchangeRate() == null){
            throw new BusinessException(SystemError.SYS_411);
        }
        switch (rateExchangeType){
            //计划兑换率
            case CurrencyRateExchangeConstant.PLANNED_EXCHANGE_RATE_:
                return currency.getPlannedExchangeRate().multiply(amount);
            //门市兑换率
            case CurrencyRateExchangeConstant.MARKET_EXCHANGE_RATE_:
                return currency.getMarketExchangeRate().multiply(amount);
            //crm兑换率
            case CurrencyRateExchangeConstant.CRM_EXCHANGE_RATE_:
                return currency.getCrmExchangeRate().multiply(amount);
            //财务兑换率
            case CurrencyRateExchangeConstant.FINANCIAL_EXCHANGE_RATE_:
                return currency.getFinancialExchangeRate().multiply(amount);
            default:
                break;
        }
        return BigDecimal.ZERO;
    }

    /**
     * 取得某币种转港币的门市兑换率
     * @param currencyId 币种ID
     * @return 兑换率
     */
    @Override
    public BigDecimal getMarketRateById(Long currencyId) {
    	if (currencyId == null){
            throw new BusinessException(SystemError.SYS_402);
        }
        MainDataCurrency currency = getById(currencyId);
        if (currency == null || Objects.equals(currency.getIsDeleted(),1)){
            throw new BusinessException(SystemError.SYS_411);
        }
        //门市汇率
        if (currency.getMarketExchangeRate() == null){
            throw new BusinessException(SystemError.SYS_411);
        }
    	return currency.getMarketExchangeRate();
    }
    
    /**
     * 取得某币种转港币的计划兑换率
     * @param currencyId 币种ID
     * @return 兑换率
     */
    @Override
    public BigDecimal getPlanneRateById(Long currencyId) {
    	if (currencyId == null){
            throw new BusinessException(SystemError.SYS_402);
        }
        MainDataCurrency currency = getById(currencyId);
        if (currency == null || Objects.equals(currency.getIsDeleted(),1)){
            throw new BusinessException(SystemError.SYS_411);
        }
        //计划汇率
        if (currency.getPlannedExchangeRate() == null){
            throw new BusinessException(SystemError.SYS_411);
        }
    	return currency.getPlannedExchangeRate();
    }
}
